#ifndef INPUT_H
#define INPUT_H

#include <queue>

#include "../chipmunk/chipmunk.h"

#include "GL/glut.h"

#include "buttonPress.h"

//Handles all the input for the player
class Input {
	private:
        int width_; //Width of the screen
        int height_; //Height of the screen

		bool leftDown_; //Left mouse button down
		bool rightDown_; //Right

		bool changed;
		int test;
		std::queue<ButtonPress> inputQueue_;

        static Input* this_; //Pointer to this object to allow callbacks

        int keyDown_[256]; //If a given key is pressed
        cpVect mouseLoc_; //Mouse locations

        //Callback helpers - Handle callback functionality
        void keyboard(unsigned char key, int x, int y);
        void keyboardUp(unsigned char key, int x, int y);
        void mouse(int x, int y);
		void mouseClick(int button, int state, int x, int y);

		//Input();

    public:
		//Construction
        Input(int width = 0, int height = 0);
        void init();

        //Instance Retreival
        static Input* getThis();

        //Dimensional Retreival
        inline int getHeight() {return height_;}
        inline int getWidth() {return width_;}

        //Input retreival
        cpVect getDirection(); //Returns the direction of keyboard controls
        inline cpVect getMouse() {return mouseLoc_;}
        bool keyDown(int index); //Gets whether a key is down
        bool operator[](char key); //Like above
		inline bool leftButtonDown() {return leftDown_;}
		inline bool rightButtonDown() {return rightDown_;}
		inline bool hasChanged() {return changed;}
		void clearChange();
		inline std::queue<ButtonPress>* getQueue() {return &inputQueue_;}

        //Callbacks
        inline static void keyboardCb(unsigned char key, int x, int y) {getThis()->keyboard(key, x, y);}
        inline static void keyboardUpCb(unsigned char key, int x, int y) {getThis()->keyboardUp(key, x, y);}
        inline static void mouseCb(int x, int y) {getThis()->mouse(x, y);}
		inline static void mouseClickCb(int button, int state, int x, int y) {getThis()->mouseClick(button, state, x, y);}
};

#endif
